#!/usr/bin/env bash
# =============================================================================
# L2TP VPN 自动安装脚本 - 优化版
# 支持系统: CentOS 7+ / Debian 9+ / Ubuntu 18.04+ / RHEL 7+ / AlmaLinux 8+ / Rocky Linux 8+
# 原作者: Teddysun
# 优化者: ayuya_mana
# 功能: 自动安装和配置L2TP/IPSec VPN服务器
# =============================================================================

set -euo pipefail

# 颜色定义
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly NC='\033[0m'

# 常量定义
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly LOG_FILE="/var/log/l2tp_install.log"
readonly CONFIG_DIR="/etc/l2tp-vpn"
readonly BACKUP_DIR="/var/backups/l2tp-vpn"
readonly VPN_CONFIG_FILE="$CONFIG_DIR/vpn.conf"
readonly DEFAULT_IP_RANGE="192.168.18"
readonly DEFAULT_USERNAME="vpnuser"
readonly DEFAULT_DNS="8.8.8.8,8.8.4.4"

# 全局变量
OS_TYPE=""
OS_VERSION=""
OS_FAMILY=""
PACKAGE_MANAGER=""
IP_ADDRESS=""
IS_INSTALLED=false
FIREWALL_TYPE=""

# VPN配置变量
ip_range=""
psk=""
username=""
password=""
dns_servers=""

# 日志函数
log() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local color=""
    
    case "$level" in
        "INFO") color="$BLUE" ;;
        "WARN") color="$YELLOW" ;;
        "ERROR") color="$RED" ;;
        "SUCCESS") color="$GREEN" ;;
    esac
    
    echo -e "${timestamp} [${color}${level}${NC}] ${message}" | tee -a "$LOG_FILE"
}

log_info() { log "INFO" "$1"; }
log_warn() { log "WARN" "$1"; }
log_error() { log "ERROR" "$1"; }
log_success() { log "SUCCESS" "$1"; }

# 错误处理
error_exit() {
    log_error "$1"
    exit 1
}

# 显示横幅
show_banner() {
    clear
    echo -e "${BLUE}"
    echo "╔══════════════════════════════════════════════════════════════╗"
    echo "║            L2TP VPN 自动安装脚本 (优化版)                       ║"
    echo "║              适用于Linux系统 (CentOS 7+/Debian 9+)             ║"
    echo "║                   增强安全性和兼容性                            ║"
    echo "╚══════════════════════════════════════════════════════════════╝"
    echo -e "${NC}"
}

# 生成强密码
generate_password() {
    if command -v openssl >/dev/null 2>&1; then
        openssl rand -base64 16 | tr -d '/+=' | cut -c1-20
    else
        tr -dc 'A-Za-z0-9!@#$%^&*()_+-=' < /dev/urandom | head -c 20
    fi
}

# 验证IP地址
validate_ip() {
    [[ "$1" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] || return 1
    IFS='.' read -r -a octets <<< "$1"
    for octet in "${octets[@]}"; do
        [[ $octet -lt 0 || $octet -gt 255 ]] && return 1
    done
    return 0
}

# 获取服务器IP
get_server_ip() {
    local ip
    
    # 方法1: 通过网络接口获取
    ip=$(ip route get 1.1.1.1 | awk '{print $7; exit}' 2>/dev/null)
    
    # 方法2: 通过hostname获取
    [[ -z "$ip" ]] && ip=$(hostname -I | awk '{print $1}' 2>/dev/null)
    
    # 方法3: 通过外部服务获取
    if [[ -z "$ip" ]]; then
        for service in ifconfig.me ipinfo.io/ip icanhazip.com; do
            ip=$(curl -s --max-time 3 "$service" 2>/dev/null)
            validate_ip "$ip" && break
        done
    fi
    
    validate_ip "$ip" && echo "$ip" || error_exit "无法获取有效的服务器IP地址"
}

# 检测操作系统
detect_os() {
    if [[ -f /etc/os-release ]]; then
        source /etc/os-release
        OS_TYPE="$ID"
        OS_VERSION="$VERSION_ID"
        
        case "$ID" in
            centos|rhel|almalinux|rocky) OS_FAMILY="rhel" ;;
            debian|ubuntu) OS_FAMILY="debian" ;;
            fedora) OS_FAMILY="fedora" ;;
            *) OS_FAMILY="unknown" ;;
        esac
    elif [[ -f /etc/redhat-release ]]; then
        OS_TYPE="centos"
        OS_VERSION=$(rpm -q --queryformat '%{VERSION}' centos-release 2>/dev/null || echo "unknown")
        OS_FAMILY="rhel"
    elif [[ -f /etc/debian_version ]]; then
        OS_TYPE="debian"
        OS_VERSION=$(cat /etc/debian_version)
        OS_FAMILY="debian"
    else
        error_exit "无法检测操作系统类型"
    fi
    
    # 确定包管理器
    if command -v dnf >/dev/null 2>&1; then
        PACKAGE_MANAGER="dnf"
    elif command -v yum >/dev/null 2>&1; then
        PACKAGE_MANAGER="yum"
    elif command -v apt >/dev/null 2>&1; then
        PACKAGE_MANAGER="apt"
    elif command -v zypper >/dev/null 2>&1; then
        PACKAGE_MANAGER="zypper"
    elif command -v apk >/dev/null 2>&1; then
        PACKAGE_MANAGER="apk"
    else
        error_exit "无法检测包管理器"
    fi
}

# 显示系统信息
show_system_info() {
    echo -e "${BLUE}=== 系统信息 ===${NC}"
    echo
    
    detect_os
    
    # 获取系统信息
    local cpu_info=$(lscpu | grep 'Model name' | cut -d: -f2 | sed 's/^[ \t]*//')
    local memory_info=$(free -h | grep 'Mem:' | awk '{print $2}')
    local disk_info=$(df -h / | tail -1 | awk '{print $2}')
    IP_ADDRESS=$(get_server_ip)
    
    # 显示系统信息
    echo -e "${YELLOW}操作系统:${NC} $OS_TYPE $OS_VERSION"
    echo -e "${YELLOW}系统家族:${NC} $OS_FAMILY"
    echo -e "${YELLOW}处理器:${NC} $cpu_info"
    echo -e "${YELLOW}内存:${NC} $memory_info"
    echo -e "${YELLOW}磁盘空间:${NC} $disk_info"
    echo -e "${YELLOW}服务器IP:${NC} $IP_ADDRESS"
    echo -e "${YELLOW}包管理器:${NC} $PACKAGE_MANAGER"
    echo
}

# 检查是否以root用户运行
check_root() {
    [[ $EUID -eq 0 ]] || error_exit "此脚本必须以root用户运行"
}

# 检查TUN/TAP可用性
check_tun() {
    [[ -e /dev/net/tun ]] || error_exit "TUN/TAP不可用。请检查您的VPS是否支持TUN/TAP。"
}

# 检查网络连接
check_network() {
    log_info "检查网络连接..."
    ping -c 1 8.8.8.8 >/dev/null 2>&1 || error_exit "网络连接不可用，请检查网络设置"
    nslookup google.com >/dev/null 2>&1 || log_warn "DNS解析可能有问题"
    log_success "网络连接检查通过"
}

# 检查系统兼容性
check_system_compatibility() {
    log_info "检查系统兼容性..."
    
    local compatible=true
    local requirements=()
    
    # 检查操作系统版本
    case "$OS_FAMILY" in
        rhel)
            if [[ "$OS_VERSION" =~ ^[0-9]+ ]]; then
                local version_num=$(echo "$OS_VERSION" | grep -oE '[0-9]+' | head -1)
                if [[ -n "$version_num" && "$version_num" -lt 7 ]]; then
                    compatible=false
                    requirements+=("RHEL家族系统需要7+版本 (当前: $OS_VERSION)")
                fi
            fi
            ;;
        debian)
            if [[ "$OS_VERSION" =~ ^[0-9]+ ]]; then
                local version_num=$(echo "$OS_VERSION" | grep -oE '[0-9]+' | head -1)
                if [[ -n "$version_num" && "$version_num" -lt 9 ]]; then
                    compatible=false
                    requirements+=("Debian家族系统需要9+版本 (当前: $OS_VERSION)")
                fi
            fi
            ;;
        fedora)
            if [[ "$OS_VERSION" =~ ^[0-9]+ ]]; then
                local version_num=$(echo "$OS_VERSION" | grep -oE '[0-9]+' | head -1)
                if [[ -n "$version_num" && "$version_num" -lt 28 ]]; then
                    compatible=false
                    requirements+=("Fedora需要28+版本 (当前: $OS_VERSION)")
                fi
            fi
            ;;
        *)
            log_warn "未测试的操作系统: $OS_TYPE"
            ;;
    esac
    
    # 检查内存
    local mem_mb=$(free -m | awk '/Mem:/ {print $2}')
    if [[ $mem_mb -lt 512 ]]; then
        compatible=false
        requirements+=("至少512MB内存 (当前: ${mem_mb}MB)")
    fi
    
    # 检查磁盘空间
    local disk_avail=$(df / | awk 'NR==2 {print $4}')
    if [[ $disk_avail -lt 1048576 ]]; then
        compatible=false
        requirements+=("至少1GB可用磁盘空间")
    fi
    
    if ! $compatible; then
        echo -e "${RED}系统不满足最低要求:${NC}"
        for req in "${requirements[@]}"; do
            echo "  - $req"
        done
        return 1
    fi
    
    log_success "系统兼容性检查通过"
    return 0
}

# 检查安装状态
check_installation_status() {
    log_info "检查安装状态..."
    mkdir -p "$CONFIG_DIR"
    
    # 检查各组件是否已安装
    local ipsec_installed=false
    local xl2tpd_installed=false
    local kernel_configured=false
    local selinux_configured=false
    
    # 检查IPSec
    if command -v ipsec >/dev/null 2>&1 && [[ -f /etc/ipsec.conf && -f /etc/ipsec.secrets ]] && grep -q "l2tp-psk" /etc/ipsec.conf; then
        ipsec_installed=true
    fi
    
    # 检查xl2tpd
    if command -v xl2tpd >/dev/null 2>&1 && [[ -f /etc/xl2tpd/xl2tpd.conf && -f /etc/ppp/options.xl2tpd ]] && grep -q "lns default" /etc/xl2tpd/xl2tpd.conf; then
        xl2tpd_installed=true
    fi
    
    # 检查内核参数
    if [[ -f /etc/sysctl.d/99-vpn.conf ]] || grep -q "net.ipv4.ip_forward = 1" /etc/sysctl.conf; then
        kernel_configured=true
    fi
    
    # 检查SELinux状态 - 修复部分
    if command -v getenforce >/dev/null 2>&1; then
        selinux_status=$(getenforce)
        if [[ "$selinux_status" == "Enforcing" ]]; then
            # SELinux处于强制模式，需要检查相关设置
            if command -v getsebool >/dev/null 2>&1; then
                # 检查必要的SELinux布尔值
                if getsebool daemons_enable_cluster_mode 2>/dev/null | grep -q "on"; then
                    selinux_configured=true
                else
                    selinux_configured=false
                fi
            else
                # 无法检查SELinux布尔值，但SELinux是强制模式，认为未配置
                selinux_configured=false
            fi
        else
            # SELinux不是强制模式（Disabled或Permissive），认为已配置
            selinux_configured=true
        fi
    else
        # 系统没有SELinux，认为已配置
        selinux_configured=true
    fi
    
    # 更新安装状态
    IS_INSTALLED=$ipsec_installed && $xl2tpd_installed && $kernel_configured && $selinux_configured
    
    # 显示安装状态
    echo -e "${BLUE}=== 安装状态检查 ===${NC}"
    echo
    if $IS_INSTALLED; then
        echo -e "${GREEN}✓ L2TP VPN 已完整安装${NC}"
    else
        echo -e "${YELLOW}⚠ L2TP VPN 未完全安装${NC}"
        echo
        echo "各组件状态:"
        $ipsec_installed && echo -e "  IPSec: ${GREEN}✓${NC}" || echo -e "  IPSec: ${RED}✗${NC}"
        $xl2tpd_installed && echo -e "  XL2TPD: ${GREEN}✓${NC}" || echo -e "  XL2TPD: ${RED}✗${NC}"
        $kernel_configured && echo -e "  内核参数: ${GREEN}✓${NC}" || echo -e "  内核参数: ${RED}✗${NC}"
        
        # 显示SELinux状态
        if command -v getenforce >/dev/null 2>&1; then
            selinux_status=$(getenforce)
            if [[ "$selinux_status" == "Enforcing" ]]; then
                $selinux_configured && echo -e "  SELinux: ${GREEN}✓${NC}" || echo -e "  SELinux: ${RED}✗${NC}"
            else
                echo -e "  SELinux: ${GREEN}✓ (已禁用/宽容模式)${NC}"
            fi
        else
            echo -e "  SELinux: ${GREEN}✓ (未安装)${NC}"
        fi
    fi
    echo
}

# 检测防火墙类型
detect_firewall() {
    if systemctl is-active --quiet firewalld; then
        FIREWALL_TYPE="firewalld"
        return 0
    fi
    
    if command -v ufw >/dev/null 2>&1 && ufw status | grep -q "active"; then
        FIREWALL_TYPE="ufw"
        return 0
    fi
    
    if command -v iptables >/dev/null 2>&1 && iptables -L -n >/dev/null 2>&1; then
        FIREWALL_TYPE="iptables"
        return 0
    fi
    
    FIREWALL_TYPE="none"
    log_warn "未检测到活动的防火墙服务"
    return 1
}

# 获取用户确认
get_confirmation() {
    local prompt="$1"
    local default="$2"  # Y 或 N
    local confirm
    
    if [[ "$default" == "Y" ]]; then
        read -p "$prompt [Y/n]: " confirm
        [[ "$confirm" != "n" && "$confirm" != "N" ]]
    else
        read -p "$prompt [y/N]: " confirm
        [[ "$confirm" == "y" || "$confirm" == "Y" ]]
    fi
}

# 获取VPN配置
get_vpn_config() {
    echo -e "${BLUE}=== L2TP VPN 配置 ===${NC}"
    echo
    
    # 如果配置文件存在，读取现有配置
    if [[ -f "$VPN_CONFIG_FILE" ]]; then
        source "$VPN_CONFIG_FILE"
        echo -e "${YELLOW}检测到现有配置:${NC}"
        echo "服务器IP: $SERVER_IP"
        echo "IP范围: $IP_RANGE.0/24"
        echo "PSK: $PSK"
        echo "用户名: $USERNAME"
        echo "密码: $PASSWORD"
        echo "DNS服务器: $DNS_SERVERS"
        echo
        
        if get_confirmation "是否使用现有配置" "Y"; then
            ip_range="$IP_RANGE"
            psk="$PSK"
            username="$USERNAME"
            password="$PASSWORD"
            dns_servers="$DNS_SERVERS"
            return 0
        fi
    fi
    
    # 获取IP范围
    while true; do
        read -p "输入IP范围 [默认: $DEFAULT_IP_RANGE]: " ip_range_input
        ip_range="${ip_range_input:-$DEFAULT_IP_RANGE}"
        if [[ "$ip_range" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
            IFS='.' read -r -a octets <<< "$ip_range"
            local valid=true
            for octet in "${octets[@]}"; do
                if [[ $octet -lt 0 || $octet -gt 255 ]]; then
                    valid=false
                    break
                fi
            done
            if $valid; then
                break
            fi
        fi
        echo -e "${RED}无效的IP范围格式，请重新输入${NC}"
    done
    
    # 生成随机PSK
    local generated_psk=$(generate_password)
    read -p "输入PSK (预共享密钥) [默认随机生成]: " psk_input
    psk="${psk_input:-$generated_psk}"
    
    # 获取用户名
    read -p "输入用户名 [默认: $DEFAULT_USERNAME]: " username_input
    username="${username_input:-$DEFAULT_USERNAME}"
    
    # 生成随机密码
    local generated_password=$(generate_password)
    read -s -p "输入密码 [默认随机生成]: " password_input
    echo
    password="${password_input:-$generated_password}"
    
    # DNS服务器选项
    echo "选择DNS服务器:"
    echo "1. Google DNS (8.8.8.8, 8.8.4.4)"
    echo "2. Cloudflare DNS (1.1.1.1, 1.0.0.1)"
    echo "3. OpenDNS (208.67.222.222, 208.67.220.220)"
    echo "4. 自定义"
    read -p "请选择 [1-4, 默认: 1]: " dns_choice
    dns_choice="${dns_choice:-1}"
    
    case $dns_choice in
        1) dns_servers="8.8.8.8,8.8.4.4" ;;
        2) dns_servers="1.1.1.1,1.0.0.1" ;;
        3) dns_servers="208.67.222.222,208.67.220.220" ;;
        4) 
            while true; do
                read -p "输入主DNS服务器: " primary_dns
                validate_ip "$primary_dns" && break
                echo -e "${RED}无效的IP地址，请重新输入${NC}"
            done
            while true; do
                read -p "输入备用DNS服务器: " secondary_dns
                validate_ip "$secondary_dns" && break
                echo -e "${RED}无效的IP地址，请重新输入${NC}"
            done
            dns_servers="$primary_dns,$secondary_dns"
            ;;
        *) dns_servers="$DEFAULT_DNS" ;;
    esac
    
    # 显示配置摘要
    echo
    echo -e "${YELLOW}VPN配置摘要:${NC}"
    echo "服务器IP: $IP_ADDRESS"
    echo "IP范围: $ip_range.0/24"
    echo "PSK: $psk"
    echo "用户名: $username"
    echo "密码: $password"
    echo "DNS服务器: $dns_servers"
    echo
    
    # 确认继续安装
    if get_confirmation "继续安装" "Y"; then
        # 保存配置
        mkdir -p "$CONFIG_DIR"
        cat > "$VPN_CONFIG_FILE" << EOF
IP_RANGE="$ip_range"
PSK="$psk"
USERNAME="$username"
PASSWORD="$password"
SERVER_IP="$IP_ADDRESS"
DNS_SERVERS="$dns_servers"
EOF
        chmod 600 "$VPN_CONFIG_FILE"
        log_info "用户确认安装，继续执行..."
    else
        error_exit "用户取消安装"
    fi
}

# 安装软件包
install_packages() {
    log_info "正在安装必需的软件包..."
    
    case "$PACKAGE_MANAGER" in
        dnf|yum)
            # 为RHEL家族系统添加EPEL仓库
            if [[ "$OS_FAMILY" == "rhel" ]]; then
                $PACKAGE_MANAGER -y install epel-release || error_exit "安装EPEL仓库失败"
                # CentOS Stream 9需要启用CRB仓库
                if [[ "$OS_TYPE" == "centos" && "$OS_VERSION" == *"stream"* ]]; then
                    $PACKAGE_MANAGER config-manager --set-enabled crb || log_warn "启用CRB仓库失败"
                fi
            fi
            
            # 更新软件包列表
            $PACKAGE_MANAGER -y update || error_exit "更新软件包失败"
            
            # 安装必需的软件包
            $PACKAGE_MANAGER -y install \
                libreswan \
                xl2tpd \
                firewalld \
                ppp \
                policycoreutils-python-utils \
                which \
                curl \
                wget \
                net-tools \
                selinux-policy-targeted \
                setroubleshoot-server \
                || error_exit "安装必需软件包失败"
            ;;
        apt)
            # 更新软件包列表
            apt-get update || error_exit "更新软件包列表失败"
            
            # 安装必需的软件包
            apt-get -y install \
                libreswan \
                xl2tpd \
                ppp \
                firewalld \
                iptables \
                netfilter-persistent \
                curl \
                wget \
                net-tools \
                selinux-utils \
                || error_exit "安装必需软件包失败"
            ;;
        zypper)
            # 更新软件包列表
            zypper --non-interactive refresh || error_exit "更新软件包列表失败"
            
            # 安装必需的软件包
            zypper --non-interactive install \
                libreswan \
                xl2tpd \
                ppp \
                firewalld \
                iptables \
                curl \
                wget \
                net-tools \
                || error_exit "安装必需软件包失败"
            ;;
        apk)
            # 更新软件包列表
            apk update || error_exit "更新软件包列表失败"
            
            # 安装必需的软件包
            apk add \
                libreswan \
                xl2tpd \
                ppp \
                firewalld \
                iptables \
                curl \
                wget \
                net-tools \
                || error_exit "安装必需软件包失败"
            ;;
        *)
            error_exit "不支持的包管理器: $PACKAGE_MANAGER"
            ;;
    esac
    
    log_success "软件包安装成功"
}

# 配置IPSec
configure_ipsec() {
    log_info "正在配置IPSec..."
    
    # 创建备份目录
    mkdir -p "$BACKUP_DIR"
    
    # 备份现有配置
    [[ -f /etc/ipsec.conf ]] && cp /etc/ipsec.conf "$BACKUP_DIR/ipsec.conf.bak"
    
    # 创建IPSec配置
    cat > /etc/ipsec.conf << EOF
version 2.0

config setup
    protostack=netkey
    nhelpers=0
    uniqueids=no
    interfaces=%defaultroute
    virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:!${ip_range}.0/24

conn l2tp-psk
    rightsubnet=vhost:%priv
    also=l2tp-psk-nonat

conn l2tp-psk-nonat
    authby=secret
    pfs=no
    auto=add
    keyingtries=3
    rekey=no
    ikelifetime=8h
    keylife=1h
    type=transport
    left=%defaultroute
    leftid=${IP_ADDRESS}
    leftprotoport=17/1701
    right=%any
    rightprotoport=17/%any
    dpddelay=40
    dpdtimeout=130
    dpdaction=clear
    sha2-truncbug=yes
EOF
    
    # 配置IPSec密钥
    cat > /etc/ipsec.secrets << EOF
%any %any : PSK "${psk}"
EOF
    
    # 设置权限
    chmod 600 /etc/ipsec.conf /etc/ipsec.secrets
    chown root:root /etc/ipsec.conf /etc/ipsec.secrets
    
    log_success "IPSec配置成功"
}

# 配置xl2tpd
configure_xl2tpd() {
    log_info "正在配置xl2tpd..."
    
    # 备份现有配置
    [[ -f /etc/xl2tpd/xl2tpd.conf ]] && cp /etc/xl2tpd/xl2tpd.conf "$BACKUP_DIR/xl2tpd.conf.bak"
    
    # 创建xl2tpd配置
    cat > /etc/xl2tpd/xl2tpd.conf << EOF
[global]
port = 1701
auth file = /etc/ppp/chap-secrets

[lns default]
ip range = ${ip_range}.2-${ip_range}.254
local ip = ${ip_range}.1
require chap = yes
refuse pap = yes
require authentication = yes
name = l2tpd
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
EOF
    
    # 配置PPP选项
    local primary_dns=$(echo "$dns_servers" | cut -d',' -f1)
    local secondary_dns=$(echo "$dns_servers" | cut -d',' -f2)
    
    cat > /etc/ppp/options.xl2tpd << EOF
ipcp-accept-local
ipcp-accept-remote
require-mschap-v2
ms-dns $primary_dns
ms-dns $secondary_dns
noccp
auth
hide-password
idle 1800
mtu 1410
mru 1410
nodefaultroute
debug
proxyarp
connect-delay 5000
EOF
    
    # 配置PPP密钥
    cat > /etc/ppp/chap-secrets << EOF
# 用于CHAP认证的密钥
# 客户端    服务器    密码    IP地址
${username}    l2tpd    ${password}       *
EOF
    
    # 设置权限
    chmod 600 /etc/xl2tpd/xl2tpd.conf /etc/ppp/options.xl2tpd /etc/ppp/chap-secrets
    chown root:root /etc/xl2tpd/xl2tpd.conf /etc/ppp/options.xl2tpd /etc/ppp/chap-secrets
    
    log_success "xl2tpd配置成功"
}

# 配置内核参数
configure_kernel() {
    log_info "正在配置内核参数..."
    
    # 备份现有的sysctl配置
    [[ -f /etc/sysctl.conf ]] && cp /etc/sysctl.conf "$BACKUP_DIR/sysctl.conf.bak"
    
    # 创建独立的VPN配置文件
    cat > /etc/sysctl.d/99-vpn.conf << EOF
# L2TP VPN 配置
net.ipv4.ip_forward = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.default.rp_filter = 0
EOF
    
    # 配置网络接口参数
    for each in /proc/sys/net/ipv4/conf/*; do
        interface=$(basename "$each")
        if [[ "$interface" != "all" && "$interface" != "default" ]]; then
            cat >> /etc/sysctl.d/99-vpn.conf << EOF
net.ipv4.conf.${interface}.accept_source_route = 0
net.ipv4.conf.${interface}.accept_redirects = 0
net.ipv4.conf.${interface}.send_redirects = 0
net.ipv4.conf.${interface}.rp_filter = 0
EOF
        fi
    done
    
    # 应用内核参数
    sysctl --system || error_exit "应用内核参数失败"
    
    log_success "内核参数配置成功"
}

# 配置防火墙
configure_firewall() {
    log_info "正在配置防火墙..."
    
    # 检测防火墙状态
    if ! detect_firewall; then
        log_warn "未检测到活动的防火墙服务，请手动配置防火墙规则"
        return 0
    fi
    
    case "$FIREWALL_TYPE" in
        firewalld)
            # 配置firewalld规则
            firewall-cmd --permanent --add-service=ipsec || log_warn "添加ipsec服务失败"
            firewall-cmd --permanent --add-port=1701/udp || log_warn "添加1701/udp端口失败"
            firewall-cmd --permanent --add-port=4500/udp || log_warn "添加4500/udp端口失败"
            firewall-cmd --permanent --add-masquerade || log_warn "添加masquerade失败"
            
            # 重新加载防火墙
            firewall-cmd --reload || log_warn "重新加载firewalld失败"
            ;;
        ufw)
            # 允许VPN端口
            ufw allow 500/udp || log_warn "允许UDP 500端口失败"
            ufw allow 4500/udp || log_warn "允许UDP 4500端口失败"
            ufw allow 1701/udp || log_warn "允许UDP 1701端口失败"
            
            # 启用转发和NAT
            grep -q "net.ipv4.ip_forward=1" /etc/ufw/sysctl.conf || echo "net.ipv4.ip_forward=1" >> /etc/ufw/sysctl.conf
            
            # 添加NAT规则
            if ! grep -q "*nat" /etc/ufw/before.rules; then
                cat >> /etc/ufw/before.rules << EOF

# NAT rules for L2TP VPN
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s ${ip_range}.0/24 -j SNAT --to-source ${IP_ADDRESS}
COMMIT
EOF
            fi
            
            # 重新加载ufw
            ufw reload || log_warn "重新加载ufw失败"
            ;;
        iptables)
            # 添加VPN端口规则
            iptables -A INPUT -p udp --dport 500 -j ACCEPT || log_warn "添加UDP 500规则失败"
            iptables -A INPUT -p udp --dport 4500 -j ACCEPT || log_warn "添加UDP 4500规则失败"
            iptables -A INPUT -p udp --dport 1701 -j ACCEPT || log_warn "添加UDP 1701规则失败"
            
            # 添加转发和NAT规则
            iptables -A FORWARD -s ${ip_range}.0/24 -j ACCEPT || log_warn "添加FORWARD规则失败"
            iptables -t nat -A POSTROUTING -s ${ip_range}.0/24 -j SNAT --to-source ${IP_ADDRESS} || log_warn "添加SNAT规则失败"
            
            # 保存iptables规则
            if command -v iptables-save >/dev/null 2>&1; then
                iptables-save > /etc/iptables/rules.v4 2>/dev/null || log_warn "保存iptables规则失败"
            fi
            ;;
        *)
            log_warn "未知的防火墙类型: $FIREWALL_TYPE"
            ;;
    esac
    
    log_success "防火墙配置成功"
}

# 配置SELinux
configure_selinux() {
    log_info "配置SELinux策略..."
    
    # 检查SELinux是否启用
    if ! command -v getenforce >/dev/null 2>&1 || [[ "$(getenforce)" != "Enforcing" ]]; then
        log_info "SELinux未启用或处于宽容模式，跳过SELinux配置"
        return 0
    fi
    
    # 安装SELinux管理工具
    case "$PACKAGE_MANAGER" in
        dnf|yum)
            $PACKAGE_MANAGER -y install setroubleshoot-server policycoreutils-python-utils || log_warn "安装SELinux工具失败"
            ;;
        apt)
            apt-get -y install setroubleshoot || log_warn "安装SELinux工具失败"
            ;;
    esac
    
    # 设置必要的SELinux布尔值
    setsebool -P daemons_enable_cluster_mode=1 2>/dev/null || log_warn "设置daemons_enable_cluster_mode失败"
    setsebool -P nis_enabled=1 2>/dev/null || log_warn "设置nis_enabled失败"
    setsebool -P allow_daemons_use_tty=1 2>/dev/null || log_warn "设置allow_daemons_use_tty失败"
    setsebool -P allow_ipsec_labeled_vpn=1 2>/dev/null || log_warn "设置allow_ipsec_labeled_vpn失败"
    
    # 为libreswan设置SELinux上下文
    command -v restorecon >/dev/null 2>&1 && restorecon -Rv /etc/ipsec.d /etc/ipsec.secrets 2>/dev/null || log_warn "恢复SELinux上下文失败"
    
    log_success "SELinux策略配置完成"
}

# 启动服务
start_services() {
    log_info "正在启动服务..."
    
    # 确保网络服务正常
    systemctl restart network-online.target || log_warn "重启网络服务失败"
    sleep 2
    
    # 启用并启动IPSec
    systemctl enable ipsec || log_warn "启用ipsec服务失败"
    systemctl restart ipsec || error_exit "启动IPSec服务失败"
    
    # 等待IPSec完全启动
    sleep 3
    
    # 启用并启动xl2tpd
    systemctl enable xl2tpd || log_warn "启用xl2tpd服务失败"
    systemctl restart xl2tpd || error_exit "启动xl2tpd服务失败"
    
    # 等待服务启动
    sleep 5
    
    # 检查服务状态
    if systemctl is-active --quiet ipsec; then
        log_success "IPSec服务启动成功"
    else
        log_error "IPSec服务启动失败"
        systemctl status ipsec >> "$LOG_FILE" 2>&1
        return 1
    fi
    
    if systemctl is-active --quiet xl2tpd; then
        log_success "xl2tpd服务启动成功"
    else
        log_error "xl2tpd服务启动失败"
        systemctl status xl2tpd >> "$LOG_FILE" 2>&1
        return 1
    fi
    
    return 0
}

# 验证安装
verify_installation() {
    log_info "正在验证安装..."
    
    local verification_passed=true
    
    # 检查IPSec服务
    systemctl is-active --quiet ipsec || {
        log_error "IPSec服务未运行"
        verification_passed=false
    }
    
    # 检查xl2tpd服务
    systemctl is-active --quiet xl2tpd || {
        log_error "xl2tpd服务未运行"
        verification_passed=false
    }
    
    # 检查IPSec连接状态
    if command -v ipsec >/dev/null 2>&1; then
        log_info "运行IPSec验证..."
        ipsec verify | grep -q "OK" || {
            log_warn "IPSec验证发现问题，请检查日志"
            ipsec verify >> "$LOG_FILE" 2>&1
        }
    fi
    
    # 检查端口监听
    if netstat -uln | grep -q ":500 " && netstat -uln | grep -q ":4500 " && netstat -uln | grep -q ":1701 "; then
        log_success "VPN端口监听正常"
    else
        log_error "VPN端口未正确监听"
        verification_passed=false
    fi
    
    # 检查内核参数
    if sysctl net.ipv4.ip_forward | grep -q "= 1"; then
        log_success "IP转发已启用"
    else
        log_error "IP转发未启用"
        verification_passed=false
    fi
    
    # 检查SELinux状态
    if command -v getenforce >/dev/null 2>&1 && [[ "$(getenforce)" == "Enforcing" ]]; then
        if command -v getsebool >/dev/null 2>&1 && getsebool daemons_enable_cluster_mode | grep -q "on"; then
            log_success "SELinux策略配置正确"
        else
            log_warn "SELinux布尔值未正确设置"
        fi
    fi
    
    if $verification_passed; then
        log_success "L2TP VPN安装完成并验证成功！"
        return 0
    else
        log_error "L2TP VPN安装验证失败！"
        return 1
    fi
}

# 显示连接信息
display_connection_info() {
    echo -e "${GREEN}=== L2TP VPN 安装完成 ===${NC}"
    echo
    echo -e "${YELLOW}连接信息:${NC}"
    echo "服务器IP: $IP_ADDRESS"
    echo "PSK: $psk"
    echo "用户名: $username"
    echo "密码: $password"
    echo "DNS服务器: $dns_servers"
    echo
    
    echo -e "${YELLOW}重要提示:${NC}"
    echo "1. 请将此信息保存在安全的地方"
    echo "2. 确保在云平台的防火墙中开放UDP端口500、4500和1701"
    echo "3. 使用提供的凭据连接到您的VPN"
    echo
    
    echo -e "${BLUE}客户端配置说明:${NC}"
    echo "Windows: https://docs.microsoft.com/zh-cn/windows-server/remote/remote-access/vpn/always-on-vpn/deploy/vpn-deploy-l2tp"
    echo "macOS: https://support.apple.com/zh-cn/guide/mac-help/connect-your-mac-to-a-vpn-mchlp1540"
    echo "iOS/Android: 使用内置的L2TP/IPSec VPN客户端"
    echo
}

# 添加用户
add_user() {
    local username="$1"
    local password="$2"
    
    [[ -z "$username" ]] && error_exit "需要提供用户名"
    
    # 如果密码为空，自动生成一个
    if [[ -z "$password" ]]; then
        password=$(generate_password)
        echo -e "${GREEN}已自动生成密码: $password${NC}"
    fi
    
    # 验证用户名格式
    [[ ! "$username" =~ ^[a-zA-Z0-9_-]+$ ]] && error_exit "用户名只能包含字母、数字、下划线和连字符"
    
    # 检查用户是否已存在
    grep -q "^$username" /etc/ppp/chap-secrets && error_exit "用户 '$username' 已存在"
    
    # 添加用户
    echo "$username    l2tpd    $password    *" >> /etc/ppp/chap-secrets
    chmod 600 /etc/ppp/chap-secrets
    
    log_info "用户 '$username' 添加成功"
    echo -e "${GREEN}用户 '$username' 添加成功${NC}"
    
    # 显示用户连接信息
    echo -e "${GREEN}=== 用户连接信息 ===${NC}"
    echo
    echo -e "${YELLOW}用户账号:${NC} $username"
    echo -e "${YELLOW}密码:${NC} $password"
    echo -e "${YELLOW}服务器IP:${NC} $IP_ADDRESS"
    echo -e "${YELLOW}预共享密钥(PSK):${NC} $psk"
    echo
}

# 删除用户
delete_user() {
    local username="$1"
    
    [[ -z "$username" ]] && error_exit "需要提供用户名"
    
    # 检查用户是否存在
    grep -q "^$username" /etc/ppp/chap-secrets || error_exit "用户 '$username' 不存在"
    
    # 删除用户
    sed -i "/^$username/d" /etc/ppp/chap-secrets
    
    log_info "用户 '$username' 删除成功"
    echo -e "${GREEN}用户 '$username' 删除成功${NC}"
}

# 列出所有用户
list_users() {
    echo -e "${BLUE}L2TP VPN 用户列表:${NC}"
    echo "================"
    printf "%-20s %-20s\n" "用户名" "密码"
    printf "%-20s %-20s\n" "------" "------"
    
    grep -v "^#" /etc/ppp/chap-secrets | while read -r line; do
        username=$(echo "$line" | awk '{print $1}')
        password=$(echo "$line" | awk '{print $3}')
        printf "%-20s %-20s\n" "$username" "$password"
    done
}

# 显示PSK
show_psk() {
    if [[ -f "$VPN_CONFIG_FILE" ]]; then
        source "$VPN_CONFIG_FILE"
        echo -e "${GREEN}=== 预共享密钥(PSK) ===${NC}"
        echo
        echo -e "${YELLOW}当前PSK:${NC} $PSK"
        echo
    else
        echo -e "${RED}未找到VPN配置文件${NC}"
    fi
}

# 更新PSK
update_psk() {
    [[ ! -f "$VPN_CONFIG_FILE" ]] && {
        echo -e "${RED}未找到VPN配置文件${NC}"
        return 1
    }
    
    source "$VPN_CONFIG_FILE"
    
    echo -e "${BLUE}=== 更新预共享密钥(PSK) ===${NC}"
    echo
    echo -e "${YELLOW}当前PSK:${NC} $PSK"
    echo
    
    # 生成新的PSK或获取用户输入
    local new_psk=$(generate_password)
    read -p "输入新的PSK [默认随机生成]: " psk_input
    new_psk="${psk_input:-$new_psk}"
    
    # 更新配置文件
    sed -i "s/PSK=\"$PSK\"/PSK=\"$new_psk\"/" "$VPN_CONFIG_FILE"
    
    # 更新IPSec密钥文件
    [[ -f /etc/ipsec.secrets ]] && sed -i "s/%any %any : PSK \"$PSK\"/%any %any : PSK \"$new_psk\"/" /etc/ipsec.secrets
    
    # 更新全局变量
    psk="$new_psk"
    
    # 重启IPSec服务
    systemctl restart ipsec
    
    echo -e "${GREEN}PSK已更新为: $new_psk${NC}"
    echo -e "${YELLOW}IPSec服务已重启${NC}"
}

# 显示服务状态
show_status() {
    echo -e "${BLUE}=== VPN 服务状态 ===${NC}"
    echo
    
    # 显示IPSec服务状态
    echo "IPSec 服务: "
    if systemctl is-active --quiet ipsec; then
        echo -e "  状态: ${GREEN}运行中${NC}"
    else
        echo -e "  状态: ${RED}已停止${NC}"
    fi
    
    # 显示xl2tpd服务状态
    echo "xl2tpd 服务: "
    if systemctl is-active --quiet xl2tpd; then
        echo -e "  状态: ${GREEN}运行中${NC}"
    else
        echo -e "  状态: ${RED}已停止${NC}"
    fi
    
    # 显示防火墙状态
    echo "防火墙状态: "
    if detect_firewall >/dev/null 2>&1; then
        echo -e "  类型: ${GREEN}$FIREWALL_TYPE${NC}"
        echo -e "  状态: ${GREEN}运行中${NC}"
    else
        echo -e "  状态: ${RED}未运行${NC}"
    fi
    
    # 显示SELinux状态
    if command -v getenforce >/dev/null 2>&1; then
        echo "SELinux 状态: $(getenforce)"
    else
        echo "SELinux 状态: 未安装"
    fi
    
    echo
}

# 重启服务
restart_services() {
    echo -e "${BLUE}=== 重启 VPN 服务 ===${NC}"
    echo
    
    systemctl restart ipsec || {
        log_error "重启IPSec服务失败"
        return 1
    }
    systemctl restart xl2tpd || {
        log_error "重启xl2tpd服务失败"
        return 1
    }
    sleep 3
    
    if systemctl is-active --quiet ipsec && systemctl is-active --quiet xl2tpd; then
        echo -e "${GREEN}VPN 服务重启成功${NC}"
        return 0
    else
        echo -e "${RED}VPN 服务重启失败${NC}"
        return 1
    fi
}

# 卸载VPN（修复版本）
uninstall_vpn() {
    echo -e "${RED}=== 卸载 L2TP VPN ===${NC}"
    echo
    echo -e "${YELLOW}警告: 此操作将完全卸载L2TP VPN服务并删除所有配置${NC}"
    echo -e "${YELLOW}包括：软件包、配置文件、防火墙规则、日志文件等${NC}"
    echo
    
    # 修复确认逻辑：默认是取消，输入y才确认卸载
    if ! get_confirmation "确认卸载? 此操作不可逆" "N"; then
        echo "卸载操作已取消"
        return 1  # 返回非零状态码表示取消卸载
    fi
    
    log_info "正在卸载L2TP VPN..."
    
    # 1. 停止并禁用服务
    systemctl stop ipsec xl2tpd 2>/dev/null || true
    systemctl disable ipsec xl2tpd 2>/dev/null || true
    
    # 2. 清理防火墙规则
    case "$FIREWALL_TYPE" in
        firewalld)
            # 移除VPN相关服务
            firewall-cmd --permanent --remove-service=ipsec 2>/dev/null || true
            firewall-cmd --permanent --remove-port=1701/udp 2>/dev/null || true
            firewall-cmd --permanent --remove-port=4500/udp 2>/dev/null || true
            firewall-cmd --permanent --remove-masquerade 2>/dev/null || true
            firewall-cmd --reload 2>/dev/null || true
            ;;
        ufw)
            # 移除VPN端口规则
            ufw delete allow 500/udp 2>/dev/null || true
            ufw delete allow 4500/udp 2>/dev/null || true
            ufw delete allow 1701/udp 2>/dev/null || true
            
            # 移除NAT规则
            if [[ -f /etc/ufw/before.rules ]]; then
                sed -i '/# NAT rules for L2TP VPN/,/^COMMIT$/d' /etc/ufw/before.rules
                ufw reload 2>/dev/null || true
            fi
            ;;
        iptables)
            # 移除VPN相关规则
            iptables -D INPUT -p udp --dport 500 -j ACCEPT 2>/dev/null || true
            iptables -D INPUT -p udp --dport 4500 -j ACCEPT 2>/dev/null || true
            iptables -D INPUT -p udp --dport 1701 -j ACCEPT 2>/dev/null || true
            iptables -D FORWARD -s ${ip_range}.0/24 -j ACCEPT 2>/dev/null || true
            iptables -t nat -D POSTROUTING -s ${ip_range}.0/24 -j SNAT --to-source ${IP_ADDRESS} 2>/dev/null || true
            
            # 保存iptables规则
            if command -v iptables-save >/dev/null 2>&1; then
                iptables-save > /etc/iptables/rules.v4 2>/dev/null || true
            fi
            ;;
    esac
    
    # 3. 删除软件包
    case "$PACKAGE_MANAGER" in
        dnf|yum)
            $PACKAGE_MANAGER -y remove libreswan xl2tpd ppp || log_warn "卸载软件包失败"
            # 清理yum/dnf缓存
            $PACKAGE_MANAGER clean all 2>/dev/null || true
            ;;
        apt)
            apt-get -y remove --purge libreswan xl2tpd ppp || log_warn "卸载软件包失败"
            apt-get -y autoremove || log_warn "自动移除依赖包失败"
            apt-get -y autoclean || log_warn "清理apt缓存失败"
            ;;
        zypper)
            zypper --non-interactive remove libreswan xl2tpd ppp || log_warn "卸载软件包失败"
            zypper --non-interactive clean || log_warn "清理zypper缓存失败"
            ;;
        apk)
            apk del libreswan xl2tpd ppp || log_warn "卸载软件包失败"
            apk cache clean || log_warn "清理apk缓存失败"
            ;;
    esac
    
    # 4. 删除配置文件和目录
    rm -rf /etc/ipsec* /etc/xl2tpd /etc/ppp/chap-secrets 2>/dev/null || true
    rm -f /etc/sysctl.d/99-vpn.conf 2>/dev/null || true
    rm -f /etc/ppp/options.xl2tpd 2>/dev/null || true
    
    # 5. 恢复内核参数
    rm -f /etc/sysctl.d/99-vpn.conf 2>/dev/null || true
    if [[ -f "$BACKUP_DIR/sysctl.conf.bak" ]]; then
        cp "$BACKUP_DIR/sysctl.conf.bak" /etc/sysctl.conf
        log_info "已恢复原始sysctl.conf"
    else
        # 如果没有备份，移除可能添加的VPN相关配置
        sed -i '/# L2TP VPN 配置/,/^$/d' /etc/sysctl.conf 2>/dev/null || true
    fi
    sysctl --system 2>/dev/null || true
    sysctl -p 2>/dev/null || true
    
    # 6. 重置SELinux策略
    if command -v getsebool >/dev/null 2>&1; then
        setsebool -P daemons_enable_cluster_mode=0 2>/dev/null || true
        setsebool -P nis_enabled=0 2>/dev/null || true
        setsebool -P allow_daemons_use_tty=0 2>/dev/null || true
        setsebool -P allow_ipsec_labeled_vpn=0 2>/dev/null || true
        log_info "SELinux策略已重置"
    fi
    
    # 7. 清理自定义配置和日志
    rm -rf "$CONFIG_DIR" 2>/dev/null || true
    rm -rf "$BACKUP_DIR" 2>/dev/null || true
    rm -f "$LOG_FILE" 2>/dev/null || true
    
    # 8. 清理临时文件
    rm -rf /tmp/l2tp-vpn-* 2>/dev/null || true
    rm -rf /tmp/ipsec-* 2>/dev/null || true
    
    # 9. 清理系统服务残留
    systemctl daemon-reload 2>/dev/null || true
    systemctl reset-failed 2>/dev/null || true
    
    log_success "L2TP VPN卸载完成"
    echo -e "${GREEN}L2TP VPN已成功卸载，所有配置和日志已清理${NC}"
    return 0  # 返回0表示卸载成功
}

# 显示主菜单
show_main_menu() {
    echo -e "${BLUE}=== 主菜单 ===${NC}"
    echo
    if $IS_INSTALLED; then
        echo "1. 添加VPN用户"
        echo "2. 删除VPN用户"
        echo "3. 列出所有用户"
        echo "4. 显示连接信息"
        echo "5. 显示PSK"
        echo "6. 更新PSK"
        echo "7. 重启服务"
        echo "8. 卸载VPN"
        echo "9. 显示服务状态"
        echo "0. 退出"
    else
        echo "1. 安装L2TP VPN"
        echo "0. 退出"
    fi
    echo
}

# 处理主菜单
handle_main_menu() {
    local choice
    
    while true; do
        show_main_menu
        read -p "请选择操作: " choice
        
        case $choice in
            1)
                if $IS_INSTALLED; then
                    read -p "输入用户名: " username
                    read -s -p "输入密码 (留空自动生成): " password
                    echo
                    add_user "$username" "$password"
                else
                    main_install
                fi
                ;;
            2)
                if $IS_INSTALLED; then
                    read -p "输入要删除的用户名: " username
                    delete_user "$username"
                else
                    echo -e "${RED}无效选择${NC}"
                fi
                ;;
            3)
                if $IS_INSTALLED; then
                    list_users
                else
                    echo -e "${RED}无效选择${NC}"
                fi
                ;;
            4)
                if $IS_INSTALLED; then
                    if [[ -f "$VPN_CONFIG_FILE" ]]; then
                        source "$VPN_CONFIG_FILE"
                        display_connection_info
                    else
                        echo -e "${RED}未找到VPN配置文件${NC}"
                    fi
                else
                    echo -e "${RED}无效选择${NC}"
                fi
                ;;
            5)
                if $IS_INSTALLED; then
                    show_psk
                else
                    echo -e "${RED}无效选择${NC}"
                fi
                ;;
            6)
                if $IS_INSTALLED; then
                    update_psk
                else
                    echo -e "${RED}无效选择${NC}"
                fi
                ;;
            7)
                if $IS_INSTALLED; then
                    restart_services
                else
                    echo -e "${RED}无效选择${NC}"
                fi
                ;;
            8)
                if $IS_INSTALLED; then
                    # 修复：根据卸载函数的返回值决定是否更新IS_INSTALLED状态
                    if uninstall_vpn; then
                        IS_INSTALLED=false
                    fi
                else
                    echo -e "${RED}无效选择${NC}"
                fi
                ;;
            9)
                if $IS_INSTALLED; then
                    show_status
                else
                    echo -e "${RED}无效选择${NC}"
                fi
                ;;
            0)
                echo -e "${GREEN}退出脚本${NC}"
                exit 0
                ;;
            *)
                echo -e "${RED}无效选择，请重新输入${NC}"
                ;;
        esac
        
        echo
        read -p "按回车键继续..."
        echo
    done
}

# 主安装函数
main_install() {
    # 执行安装步骤
    check_network || error_exit "网络检查失败"
    log_info "检查网络连接完成"
    
    check_system_compatibility || error_exit "系统兼容性检查失败"
    log_info "系统兼容性检查完成"
    
    get_vpn_config || error_exit "获取VPN配置失败"
    log_info "VPN配置获取完成"
    
    install_packages || error_exit "安装软件包失败"
    log_info "软件包安装完成"
    
    configure_ipsec || error_exit "配置IPSec失败"
    log_info "IPSec配置完成"
    
    configure_xl2tpd || error_exit "配置xl2tpd失败"
    log_info "xl2tpd配置完成"
    
    configure_kernel || error_exit "配置内核参数失败"
    log_info "内核参数配置完成"
    
    configure_firewall || error_exit "配置防火墙失败"
    log_info "防火墙配置完成"
    
    configure_selinux || error_exit "配置SELinux失败"
    log_info "SELinux配置完成"
    
    start_services || error_exit "启动服务失败"
    log_info "服务启动完成"
    
    verify_installation || error_exit "验证安装失败"
    log_info "安装验证完成"
    
    # 显示连接信息
    display_connection_info
    
    # 更新安装状态
    IS_INSTALLED=true
    
    log_success "L2TP VPN安装完成"
}

# 主函数
main() {
    # 显示横幅
    show_banner
    
    # 检查root权限
    check_root
    
    # 检查TUN/TAP
    check_tun
    
    # 显示系统信息
    show_system_info
    
    # 检查安装状态
    check_installation_status
    
    # 创建必要的目录
    mkdir -p "$CONFIG_DIR" "$BACKUP_DIR"
    
    # 处理主菜单
    handle_main_menu
}

# 脚本入口点
main "$@"